package com.honglang.rss.impl;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

public class RSSStreamWriter {
	private String file;
	
	private XMLOutputFactory xmlOutputFactory;
	private XMLStreamWriter xmlSteamWriter;
	private String encoding  = "UTF-8";
	
	
	
	public RSSStreamWriter(String file,String encoding) throws FileNotFoundException, XMLStreamException{
		this.setXmlOutputFactory(XMLOutputFactory.newInstance());
		this.setFile(file);
		this.encoding = encoding;
		this.setXmlSteamWriter(this.getXmlOutputFactory().createXMLStreamWriter(new FileOutputStream(this.getFile()),encoding));
	}
	
	
	protected void writeEnter() throws XMLStreamException{
		this.getXmlSteamWriter().writeCharacters("\n");
	}
	
	
	protected void writeTab(int count) throws XMLStreamException{
		for(int i=count;i>0;i--){
			this.getXmlSteamWriter().writeCharacters("\t");
		}
	}
	
	
	
	
	
	protected void startRss() throws XMLStreamException{
		this.getXmlSteamWriter().writeStartDocument(encoding, "1.0");
		this.writeEnter();
		
		this.getXmlSteamWriter().writeStartElement("rss");
		this.getXmlSteamWriter().writeAttribute("version", "2.0");
		this.writeEnter();
	}
	
	protected void endRss() throws XMLStreamException {
		this.getXmlSteamWriter().writeEndElement();
		this.getXmlSteamWriter().writeEndDocument();
		this.getXmlSteamWriter().flush();
		this.getXmlSteamWriter().close();
	}
	
	
	protected void writeChannle(Channel channel) throws XMLStreamException{
		this.writeTab(1);
		this.getXmlSteamWriter().writeStartElement("channel");
		this.writeEnter();
		for(Method method : channel.getClass().getMethods()){
			if(method.getReturnType().equals(String.class) && method.getName().substring(0, 3).equals("get")){
				
					String value;
					try {
						value = (String)method.invoke(channel, new Object[]{});
						if(value != null && !value.isEmpty()){
							this.createNode(method.getName().substring(3,4).toLowerCase() + method.getName().substring(4),value,2 );
						}
					} catch (IllegalArgumentException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IllegalAccessException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (InvocationTargetException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					
				
			}
		}
		for(Item item :channel.getItemList()){
			this.writeItem(item);
		}
		this.writeTab(1);
		this.getXmlSteamWriter().writeEndElement();
		this.writeEnter();
		
	}
	
	protected void writeItem(Item item) throws XMLStreamException{
		this.writeTab(2);
		this.getXmlSteamWriter().writeStartElement("item");
		this.writeEnter();
		for(Method method : item.getClass().getMethods()){
			if(method.getReturnType().equals(String.class) && method.getName().substring(0, 3).equals("get")){
				try {
					String value = (String)method.invoke(item, new Object[]{});
					if(value != null && !value.isEmpty()){
						this.createNode(method.getName().substring(3,4).toLowerCase() + method.getName().substring(4),value,3);
					}
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} 
			}
		}
		this.writeTab(2);
		this.getXmlSteamWriter().writeEndElement();
		this.writeEnter();
	}
	
	
	protected void createNode(String name ,String value,int tabCount) throws XMLStreamException{
		this.writeTab(tabCount);
		this.getXmlSteamWriter().writeStartElement(name);
		this.getXmlSteamWriter().writeCharacters(value);
		this.getXmlSteamWriter().writeEndElement();
		this.writeEnter();
	}
	
	
	
	
	public void createRss(Channel channel) throws XMLStreamException{
		this.startRss();
		this.writeChannle(channel);
		this.endRss();
		
	}
	
	public void createRss(List<Channel> channelList) throws XMLStreamException{
		this.startRss();
		for(Channel channel :channelList){
			this.writeChannle(channel);
		}
		this.endRss();
	}
	
	
	
	
	protected String getFile() {
		return file;
	}

	protected void setFile(String file) {
		this.file = file;
	}

	protected XMLOutputFactory getXmlOutputFactory() {
		return xmlOutputFactory;
	}

	protected void setXmlOutputFactory(XMLOutputFactory xmlOutputFactory) {
		this.xmlOutputFactory = xmlOutputFactory;
	}


	protected XMLStreamWriter getXmlSteamWriter() {
		return xmlSteamWriter;
	}


	protected void setXmlSteamWriter(XMLStreamWriter xmlSteamWriter) {
		this.xmlSteamWriter = xmlSteamWriter;
	}
	
	public static void main(String[] args){
		Item item = new Item();
		item.setTitle("123");
		item.setDescription("Sdfsa$&<\nfsdfasd");
		
		Item item1 = new Item();
		item1.setTitle("123");
		item1.setDescription("Sdfs 的。dfasd");
		Channel channel = new Channel("aaa","cccc","ddd");
		channel.addItem(item);
		channel.addItem(item1);
		
		try {
			RSSStreamWriter rssStreamWriter = new RSSStreamWriter("E:\\c.xml","UTF-8");
			rssStreamWriter.createRss(channel);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XMLStreamException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}
